package com.fy56.platform.logistics.restful.api.controller.wx;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fy56.platform.logistics.model.*;
import com.fy56.platform.logistics.service.web.IMiniProgramService;
import com.fy56.platform.logistics.service.web.IWeChatProgramService;
import com.fy56.platform.logistics.service.wx.ICompanyInfoService;
import com.fy56.platform.logistics.service.wx.IOrderService;
import com.fy56.platform.logistics.service.wx.IVipService;
import com.fy56.platform.logistics.utils.HttpClientUtils;
import com.fy56.platform.logistics.utils.HttpUtil;
import com.fy56.platform.logistics.utils.StringUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.wordnik.swagger.annotations.Api;
import com.zeus.base.privilege.utils.HttpClientUtil;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author by Edwin Yang on 2018/2/28 0028.
 */
@Api(value = "wxUtil", description = "微信工具类", produces = MediaType.APPLICATION_JSON_VALUE)
@RestController
@RequestMapping("/wxUtil")
public class wxController {

    private String result;
/*    private String code = "001ZuLM41jKsvL1T6cM41TYPM41ZuLMm";
    private String appid = "wx881c5f23c98d2b34";*/

    @Autowired
    private IVipService vipService;

    @Autowired
    private ICompanyInfoService iCompanyInfoService;

    @Autowired
    private IWeChatProgramService iWeChatProgramService;

    @Autowired
    private IMiniProgramService iMiniProgramService;

    @Autowired
    private IOrderService iOrderService;

    private static Logger log = Logger.getLogger(wxController.class);

    @RequestMapping("/getOpenId")
    public ResponseEntity getOpenId(@RequestParam String code,@RequestParam String tenantCode,@RequestParam String latitude,@RequestParam String longitude){
        Long b = System.currentTimeMillis();//开始时间
        Map returnMap = new HashMap();
        if(StringUtil.isEmpty(code)){
            Result r = new Result(false, "参数code为空", "", "");
            result = JSON.toJSONString(r);
            return new ResponseEntity<>(result, HttpStatus.OK);
        }
        Long begin = System.currentTimeMillis();//开始时间
        MiniProgram miniProgram = iMiniProgramService.selectByCode(tenantCode);
        if(miniProgram == null || StringUtil.isEmpty(miniProgram.getAppid())){
            Result r = new Result(false, "该小程序项目不存在或已关闭，金融代码[" + tenantCode + "]", "", "");
            result = JSON.toJSONString(r);
            return new ResponseEntity<>(result, HttpStatus.OK);
        }
        Long end = System.currentTimeMillis();//结束时间
        log.info("getOpenId  miniProgram：" + (end - begin) + "毫秒。");
        begin = System.currentTimeMillis();//开始时间
        String url = "https://api.weixin.qq.com/sns/jscode2session"
                + "?js_code=" + code
                + "&appid=" + miniProgram.getAppid()
                + "&secret=" + miniProgram.getSecret() + "&grant_type=authorization_code";
        try {
            String retStr = HttpClientUtils.postParameters(url,"");
            Long endweixin = System.currentTimeMillis();//结束时间
            log.info("getOpenId qq：" + (endweixin - begin) + "毫秒。");
            returnMap = JSON.parseObject(retStr);
            if(returnMap!=null && returnMap.get("openid")!=null){
                String openid = returnMap.get("openid").toString();
                //根据OpenId获取对应Vip信息
                begin = System.currentTimeMillis();//开始时间
                Vip user =  vipService.selectByOpenId(openid);
                 end = System.currentTimeMillis();//结束时间
                log.info("getOpenId  user：" + (end - begin) + "毫秒。");
                Result r = new Result(true, "成功", returnMap.get("session_key").toString(), openid);
                //小程序金融代码
                r.setTenantCode(miniProgram.getTenantCode());
                //小程序应用名称
                r.setAppName(miniProgram.getAppName());
                //小程序应用名称
                r.setAppId(miniProgram.getAppid());
                if(user!=null){
                    r.setUserId((user.getId()));
                    r.setLoginName(user.getName());
                    r.setUser(user);
                    user.setOpenId(openid);
                }
                begin = System.currentTimeMillis();//开始时间
                //如果是定制版，设置企业信息
                if(StringUtil.isNotEmpty(tenantCode)&&!"FYGB2020".equals(tenantCode) &&!"MXFWH-NC01".equals(tenantCode)){
                    Long companystart = System.currentTimeMillis();//结束时间
                    Company company = iCompanyInfoService.getCompanyByCode(tenantCode);
                    Long companyend = System.currentTimeMillis();//结束时间
                    log.info("getCompany总用时：" + (companyend - companystart) + "毫秒。");
                    r.setCompany(company);

                    //---设置下单的基本信息---//
                    //1.目的地
                    //2.业务相关设置 : 小程序代收是否必须输入银行信息
                    //3.业务相关设置 : 小程序有代收货款必须与默认开户银行一致
                    //4.业务相关设置 : 默认银行
                    //5.业务相关设置 : 配送（提货）方式
                    //6.默认的付款方式
                    //7.默认的配送（提货）方式
                    //8.付款方式
                    //9.包装样式
                    //10.发货人
                    //11.默认发货人
                    //12.收货人
                    //13.默认收货人
                    //14.寄件网点（从认证中心获取的子公司信息）
                    //15.银行信息
                    company.setBusinessSetting(iOrderService.getOrderBaseInfo(tenantCode,user == null ? null : user.getId(),latitude,longitude,openid,company));
                }
                end = System.currentTimeMillis();//结束时间
                log.info("getOpenId总用时：" + (end - b) + "毫秒。");
                //设置系统信息
                WeChatProgram sysInfo = iWeChatProgramService.getWeChatProgram();
                r.setSysInfo(sysInfo);

                return new ResponseEntity<>(r, HttpStatus.OK);
            }else{
                return new ResponseEntity<>(returnMap, HttpStatus.OK);
            }
        } catch (Exception e) {
            log.error("获取openid出错",e);
            return new ResponseEntity<>(e, HttpStatus.OK);
        }
    }

    @RequestMapping("/getTest")
    public ResponseEntity getTest(@RequestParam String test){
        result="ok";
        return new ResponseEntity<>(result, HttpStatus.OK);
    }
    @RequestMapping("/getTesta")
    public ResponseEntity getTesta(@RequestParam String testa){
        String url="http://47.111.81.6:40214/logistics-restful-api/wxUtil/getTest";
        Map<String,String> paramsMap = new HashMap<>();
        paramsMap.put("test" , "1");
        Long begin = System.currentTimeMillis();//开始时间
        Long after = System.currentTimeMillis();//结束时间
        for(int i=0;i<Integer.parseInt(testa);i++){
            try{
                begin = System.currentTimeMillis();//开始前时间
                String  postResult = HttpUtil.post(url,paramsMap);
                after = System.currentTimeMillis();//短信结束后时间
                log.info(i+"时间:"+(after - begin) + "毫秒。结果："+postResult);
            }catch (Exception e){
                log.error("时间error");
            }
        }

        result="ok";
        return new ResponseEntity<>(result, HttpStatus.OK);
    }
    @RequestMapping("/getTestb")
    public ResponseEntity getTestb(@RequestParam String testa){
        String url="http://es.feiyang56.cn:60060/esApi/getListByPage";
        List list = new ArrayList();
        WhereParams whereParams = new WhereParams();
        whereParams = new WhereParams();
        whereParams.setName("tenant");
        whereParams.setValue("nmgdhwl");
        whereParams.setValueType("String");
        whereParams.setQueryType("=");
        list.add(whereParams);
        whereParams = new WhereParams();
        whereParams.setName("name or nameUpperCase");
        whereParams.setValue("汇合天下");
        whereParams.setValueType("String");
        whereParams.setQueryType("like");
        list.add(whereParams);
        String  json = JSONObject.toJSONString(list);

        Map<String,String> paramsMap = new HashMap<>();
        paramsMap.put("passcode","fy56-es");
        paramsMap.put("databaseName","platform_members");
        paramsMap.put("tableName","general_members");
        paramsMap.put("startPage","1");
        paramsMap.put("pageSize","10");
        paramsMap.put("whereParams",json);//查询条件



        result="ok";
        return new ResponseEntity<>(result, HttpStatus.OK);
    }
    /**
     * 公版小程序根据金融代码重新获取公司信息
     * @param userId 用户唯一id
     * @param tenantCode 金融代码
     * @param latitude 经度
     * @param longitude 纬度
     * @return
     */
    @RequestMapping("/getPublicBasicinfo")
    public ResponseEntity getPublicBasicinfo(@RequestParam String userId,@RequestParam String tenantCode,@RequestParam String latitude,@RequestParam String longitude){
        Map returnMap = new HashMap();
//        MiniProgram miniProgram = iMiniProgramService.selectByCode(tenantCode);
//        if(miniProgram == null || StringUtil.isEmpty(miniProgram.getAppid())){
//            Result r = new Result(false, "该小程序项目不存在或已关闭，金融代码[" + tenantCode + "]", "", "");
//            result = JSON.toJSONString(r);
//            return new ResponseEntity<>(result, HttpStatus.OK);
//        }
        try {
                //根据OpenId获取对应Vip信息
                Result r = new Result(true, "成功", "", "");
                //如果是定制版，设置企业信息
                if(StringUtil.isNotEmpty(tenantCode)&&!"".equals(tenantCode)){
                    Company company = iCompanyInfoService.getCompanyByCode(tenantCode);
                    //Company company = iCompanyInfoService.queryByCompanyCode(tenantId);
                    if (company.getLongitude()!=null && ! company.getLongitude().equals("") && company.getLatitude()!=null && ! company.getLatitude().equals("")){
                        System.out.println("百度坐标 "+company.getLongitude()+":"+company.getLatitude());
                        //百度地图坐标转换成腾讯地图坐标
                        double pi = 3.141592653589793 * 3000.0 / 180.0;
                        double x = company.getLongitude() - 0.0065, y = company.getLatitude() - 0.006;
                        double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * pi);
                        double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * pi);
                        double gg_lon = z * Math.cos(theta);
                        double gg_lat = z * Math.sin(theta);
                        company.setLongitude(gg_lon);
                        company.setLatitude(gg_lat);
                        System.out.println("腾讯地图坐标 "+company.getLongitude()+":"+company.getLatitude());
                    }

                    r.setCompany(company);

                    //---设置下单的基本信息---//
                    //1.目的地
                    //2.业务相关设置 : 小程序代收是否必须输入银行信息
                    //3.业务相关设置 : 小程序有代收货款必须与默认开户银行一致
                    //4.业务相关设置 : 默认银行
                    //5.业务相关设置 : 配送（提货）方式
                    //6.默认的付款方式
                    //7.默认的配送（提货）方式
                    //8.付款方式
                    //9.包装样式
                    //10.发货人
                    //11.默认发货人
                    //12.收货人
                    //13.默认收货人
                    //14.寄件网点（从认证中心获取的子公司信息）
                    //15.银行信息
                    Long userid=Long.valueOf(1);
                    if (userId!=null&&userId.length()!=0){
                        userid=Long.parseLong(userId);
                    }
                    company.setBusinessSetting(iOrderService.getOrderBaseInfo(tenantCode,userid,latitude,longitude,"",company));
                }
                //设置系统信息
                WeChatProgram sysInfo = iWeChatProgramService.getWeChatProgram();
                r.setSysInfo(sysInfo);
                return new ResponseEntity<>(r, HttpStatus.OK);
        } catch (Exception e) {
            log.error("获取openid出错",e);
            return new ResponseEntity<>(e, HttpStatus.OK);
        }
    }



    @RequestMapping("/getUserId")
    public ResponseEntity getOpenId(@RequestParam String code,@RequestParam String tenantCode){
        Long begin = System.currentTimeMillis();//开始时间
        Map returnMap = new HashMap();
        if(com.zeus.base.privilege.utils.StringUtil.isEmpty(code)){
            Result r = new Result(false, "参数code为空", "", "");
            result = JSON.toJSONString(r);
            return new ResponseEntity<>(result, HttpStatus.OK);
        }
        MiniProgram miniProgram = iMiniProgramService.selectByCode(tenantCode);
        String appid= miniProgram.getAppid();
        String url = "https://api.weixin.qq.com/sns/jscode2session"
                + "?js_code=" + code
                + "&appid=" + miniProgram.getAppid()
                + "&secret=" + miniProgram.getSecret() + "&grant_type=authorization_code";
        try {
            log.info("getUserId url：" + url);
            String retStr = HttpClientUtil.doPost(url,"",null);
            Long endweixin = System.currentTimeMillis();//结束时间
            log.info("getUserId retStr：" + retStr);
            returnMap = JSON.parseObject(retStr);
            if(returnMap!=null && returnMap.get("openid")!=null){
                String openid = returnMap.get("openid").toString();
                //根据OpenId获取对应Vip信息
                Result r = new Result(true, "成功", returnMap.get("session_key").toString(), openid);

                Long end = System.currentTimeMillis();//结束时间
                log.info("getOpenId总用时：" + (end - begin) + "毫秒。");
                return new ResponseEntity<>(r, HttpStatus.OK);
            }else{
                Long end = System.currentTimeMillis();//结束时间
                return new ResponseEntity<>(returnMap, HttpStatus.OK);
            }
        } catch (Exception e) {
            log.error("获取openid出错",e);
            return new ResponseEntity<>(e, HttpStatus.OK);
        }
    }


    @RequestMapping("/getCompany")
    public ResponseEntity getCompany(@RequestParam String tenantCode,@RequestParam String latitude,@RequestParam String longitude){
        Long begin = System.currentTimeMillis();//开始时间
        Map returnMap = new HashMap();
        if(StringUtil.isEmpty(tenantCode)){
            Result r = new Result(false, "参数tenantCode为空", "", "");
            result = JSON.toJSONString(r);
            return new ResponseEntity<>(result, HttpStatus.OK);
        }
        try {
            MiniProgram miniProgram = iMiniProgramService.selectByCode(tenantCode);
                //根据OpenId获取对应Vip信息
                Result r = new Result(true, "成功", "", "");
                //小程序金融代码
                r.setTenantCode(miniProgram.getTenantCode());
                //小程序应用名称
                r.setAppName(miniProgram.getAppName());
                //小程序应用名称
                r.setAppId(miniProgram.getAppid());
                //如果是定制版，设置企业信息
                if(StringUtil.isNotEmpty(tenantCode)){
                    Long companystart = System.currentTimeMillis();//结束时间
                    Company company = iCompanyInfoService.getCompanyByCode(tenantCode);
                    Long companyend = System.currentTimeMillis();//结束时间
                    log.info("getCompany总用时：" + (companyend - companystart) + "毫秒。");
                    r.setCompany(company);
                    Map<String, Object> obj = Maps.newHashMap();
                    //寄件网点（从认证中心获取的子公司信息）
                    List<Company> companyList = iCompanyInfoService.getWebList(tenantCode, longitude, latitude,company);
                    if (CollectionUtils.isEmpty(companyList)) {
                        obj.put("webList", Lists.newArrayList());
                    } else {
                        obj.put("webList", companyList);
                    }
                    company.setBusinessSetting(obj);
                }
                Long end = System.currentTimeMillis();//结束时间
                log.info("getCompany总用时：" + (end - begin) + "毫秒。");
                return new ResponseEntity<>(r, HttpStatus.OK);
        } catch (Exception e) {
            log.error("获取openid出错",e);
            return new ResponseEntity<>(e, HttpStatus.OK);
        }
    }

    public String getResult() {
        return result;
    }
    public void setResult(String result) {
        this.result = result;
    }


    private class Result{
        private boolean success;
        private String msg;
        private String session_key;
        private String openid;
        private Long userId;
        private String loginName;
        private Vip user;
        private Company company;
        private WeChatProgram sysInfo;
        //金融代码
        private String tenantCode;
        //小程序应用名称
        private String appName;
        //小程序应用名称
        private String appId;
        public Result(boolean success, String msg, String session_key,
                      String openid) {
            super();
            this.success = success;
            this.msg = msg;
            this.session_key = session_key;
            this.openid = openid;
        }

        public Company getCompany() {
            return company;
        }

        public void setCompany(Company company) {
            this.company = company;
        }

        public WeChatProgram getSysInfo() {
            return sysInfo;
        }

        public void setSysInfo(WeChatProgram sysInfo) {
            this.sysInfo = sysInfo;
        }

        public boolean isSuccess() {
            return success;
        }
        public void setSuccess(boolean success) {
            this.success = success;
        }
        public String getMsg() {
            return msg;
        }
        public void setMsg(String msg) {
            this.msg = msg;
        }
        public String getSession_key() {
            return session_key;
        }
        public void setSession_key(String session_key) {
            this.session_key = session_key;
        }
        public String getOpenid() {
            return openid;
        }
        public void setOpenid(String openid) {
            this.openid = openid;
        }
        public Long getUserId() {
            return userId;
        }
        public void setUserId(Long userId) {
            this.userId = userId;
        }
        public String getLoginName() {
            return loginName;
        }
        public void setLoginName(String loginName) {
            this.loginName = loginName;
        }

        public Vip getUser() {
            return user;
        }

        public String getTenantCode() {
            return tenantCode;
        }

        public void setTenantCode(String tenantCode) {
            this.tenantCode = tenantCode;
        }

        public String getAppName() {
            return appName;
        }

        public void setAppName(String appName) {
            this.appName = appName;
        }

        public String getAppId() {
            return appId;
        }

        public void setAppId(String appId) {
            this.appId = appId;
        }

        public void setUser(Vip user) {
            this.user = user;
        }
    }
}